/*
 * Circle.java
 * RVO2 Library Java
 *
 * Copyright 2008 University of North Carolina at Chapel Hill
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Please send all bug reports to <geom@cs.unc.edu>.
 *
 * The authors may be contacted via:
 *
 * Jur van den Berg, Stephen J. Guy, Jamie Snape, Ming C. Lin, Dinesh Manocha
 * Dept. of Computer Science
 * 201 S. Columbia St.
 * Frederick P. Brooks, Jr. Computer Science Bldg.
 * Chapel Hill, N.C. 27599-3175
 * United States of America
 *
 * <http://gamma.cs.unc.edu/RVO2/>
 */

/*
 * Example file showing a demo with 250 agents initially positioned evenly
 * distributed on a circle attempting to move to the antipodal position on the
 * circle.
 */

package RVO;

import java.util.List;
import java.util.ArrayList;
import RVO.Vector2;
import RVO.Simulator;
import RVO.RVOMath;

public class Circle {
    /* Store the goals of the agents. */
    List<Vector2> goals;

    Circle() {
        goals = new ArrayList<Vector2>();
    }

    void setupScenario() {
        /* Specify the global time step of the simulation. */
        //Simulator.Instance.setTimeStep(0.25f);

        /*
         * Specify the default parameters for agents that are subsequently
         * added.
         */
        //Simulator.Instance.setAgentDefaults(15.0f, 10, 10.0f, 10.0f, 1.5f, 2.0f, new Vector2(0.0f, 0.0f));

        /*
         * Add agents, specifying their start position, and store their
         * goals on the opposite side of the environment.
         */
        for (int i = 0; i < 250; ++i) {
            //Simulator.Instance.addAgent(Vector2.multiply(new Vector2((float) Math.cos(i * 2.0f * Math.PI / 250.0f),
                    //(float) Math.sin(i * 2.0f * Math.PI / 250.0f)), 200.0f));
            //goals.add(Vector2.negate(Simulator.Instance.getAgentPosition(i)));
        }
    }

    // RVO_OUTPUT_TIME_AND_POSITIONS
    void updateVisualization() {
        /* Output the current global time. */
        //System.out.print(Simulator.Instance.getGlobalTime());

        /* Output the current position of all the agents. */
        /*
        for (int i = 0; i < Simulator.Instance.getNumAgents(); ++i) {
            System.out.print(" " + Simulator.Instance.getAgentPosition(i));
        }
         */

        System.out.println();
    }

    void setPreferredVelocities() {
        /*
         * Set the preferred velocity to be a vector of unit magnitude
         * (speed) in the direction of the goal.
         */
        /*
        for (int i = 0; i < Simulator.Instance.getNumAgents(); ++i) {
            Vector2 goalVector = Vector2.subtract(goals.get(i), Simulator.Instance.getAgentPosition(i));

            if (RVOMath.absSq(goalVector) > 1.0f) {
                goalVector = RVOMath.normalize(goalVector);
            }

            Simulator.Instance.setAgentPrefVelocity(i, goalVector);
        }
         */
    }

    boolean reachedGoal() {
        /* Check if all agents have reached their goals. */
        /*
        for (int i = 0; i < Simulator.Instance.getNumAgents(); ++i) {
            if (RVOMath.absSq(Vector2.subtract(Simulator.Instance.getAgentPosition(i), goals.get(i))) > Simulator.Instance.getAgentRadius(i) * Simulator.Instance.getAgentRadius(i)) {
                return false;
            }
        }
         */
        return true;
    }

    public static void main(String[] args) {
        Circle circle = new Circle();

        /* Set up the scenario. */
        circle.setupScenario();

        /* Perform (and manipulate) the simulation. */
        do {
            // RVO_OUTPUT_TIME_AND_POSITIONS
            circle.updateVisualization();
            circle.setPreferredVelocities();
            //Simulator.Instance.doStep();
        }
        while (!circle.reachedGoal());
    }
}
